package de.stefanocke.roo.wicket.table

import de.stefanocke.roo.wicket.Stereotypes
import de.stefanocke.roo.wicket.base.BeanPropertiesAwareItdBuilder
import de.stefanocke.roo.wicket.model.BeanPropertyMetadata
import java.lang.reflect.Modifier
import org.springframework.roo.model.JavaType

import static de.stefanocke.roo.wicket.table.TableItdBuilder.*
import static de.stefanocke.roo.xtend.Method.*
import static de.stefanocke.roo.xtend.MethodSignature.*
import static de.stefanocke.roo.xtend.Parameter.*

import static extension de.stefanocke.roo.xtend.RooExtensions.*

class TableItdBuilder extends BeanPropertiesAwareItdBuilder<TableCellComponentMetadata>{
	
	static String COLUMN_CLASS = "org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn"
	
	override TableMetadata getMetadata(){super.metadata as TableMetadata} 
	
	override String baseClassStereotype(){
		Stereotypes::TABLE	
	}
	
	override getMethods()
	{
			var methods = constructors
			methods += getCreateColumnsMethod
			methods += getCreateColumnMethods
			//factory creation methods for columns with custom component
			methods += getCreateComponentFactoryMethods(metadata.propertiesForScaffolding) 		
			methods
	}
	
//	public PostTable(String id, ISortableDataProvider<Post> dataProvider) {
//		super(id, dataProvider);
//	}
	def getConstructors(){
		newArrayList(
			constructorWithIdAndModelAndServiceBindings
		)
	}
	
	//	public KontaktForm(String id, IModel<Kontakt> model,
	//			IServiceBindings<Kontakt, ?> serviceBindings) {
	//		super(id, model, serviceBindings);
	//	}
	def constructorWithIdAndModelAndServiceBindings(){
		method(
			signature(Modifier::PUBLIC, 
				param("java.lang.String", "id"),
				param(Stereotypes::IENTITYBINDINGS.stereotype(modelClass, WILDCARD), "serviceBindings")
			),
			[|'''
			super(id, serviceBindings);
			''']
		)
	}
	
	
	//	@Override
	//	protected List<IColumn<Post>> createColumns() {
	//		List<IColumn<Post>> colums = new ArrayList<IColumn<Post>>();
	//		colums.add(createCreatedColumn());
	//		colums.add(createTitleColumn());
	//		colums.add(createUserColumn());
	//		colums.add(createTagsColumn());
	//		return colums ;
	//	}
	// TODO; We have something similar in Details and FormFields. Common parts could be moved to some superclass
	def getCreateColumnsMethod(){
		val returnType = "java.util.List".javaType(columnType)
		method(
			signature(
				Modifier::PUBLIC, returnType, "createColumns"
			),
			[|'''
			«returnType.resolve» columns = new «"java.util.ArrayList".javaType(columnType).resolve»();
			«FOR p : propertiesForScaffolding»
				columns.add(«p.getCreateColumnMethodName»());
			«ENDFOR»
			return columns;
			''']
			
		)
	}
	
	def getColumnType(){
		//TODO: Care about second type argument
		COLUMN_CLASS.javaType(modelClass, JavaType::STRING);
	}
	
	//return createColumn("user","user","user");
	//TODO: Can we use factory methods here (to create different kinds of columns depending on annotations)?
	def getCreateColumnMethods(){
			
		propertiesForScaffolding.map(p |{
			
			val name = p.getPropertyName
			val signature = signature(Modifier::PUBLIC, columnType,	p.getCreateColumnMethodName)
			
			
			method(signature,[|{'''
				«IF p.hasComponentMetadata»
				return createColumn("«name»","«name»","«name»",«p.getCreateComponentFactoryMethodName»());
				«ELSE»
				return createColumn("«name»","«name»","«name»");
				«ENDIF»
			'''}]) 
		})
		
	}
	
	def getCreateColumnMethodName(BeanPropertyMetadata p){
		"create"+p.getPropertyName.symbolNameCapitalisedFirstLetter+"Column"
	}
	
	override String getCreateComponentFactoryMethodName(BeanPropertyMetadata p){
		"create"+p.getPropertyName.symbolNameCapitalisedFirstLetter+"ColumnComponentFactory"
	}
	
	
}